#ifndef QTVISIONTEST_GEOMETRICTRANSFORMER_H
#define QTVISIONTEST_GEOMETRICTRANSFORMER_H
// GeometricTransformer.h
#pragma once
#include <opencv2/opencv.hpp>
#include <vector>

class GeometricTransformer {
public:
    // ====== 基础缩放 ======
    // 根据 scaleX/scaleY 缩放，输出尺寸自动按比例计算
    static cv::Mat Scale(const cv::Mat& src,
                         double scaleX,
                         double scaleY,
                         int interpolation = cv::INTER_LINEAR);

    // 指定输出尺寸缩放
    static cv::Mat ScaleTo(const cv::Mat& src,
                           const cv::Size& dstSize,
                           int interpolation = cv::INTER_LINEAR);

    // ====== 平移 ======
    static cv::Mat Translate(const cv::Mat& src,
                             double shiftX,
                             double shiftY,
                             cv::Size dstSize = cv::Size(),
                             int interpolation = cv::INTER_LINEAR,
                             int borderMode = cv::BORDER_CONSTANT,
                             const cv::Scalar& borderValue = cv::Scalar());

    // ====== 旋转 ======
    // 围绕图像中心旋转，输出尺寸保持不变
    static cv::Mat Rotate(const cv::Mat& src,
                          double angleDeg,
                          double scale = 1.0,
                          int interpolation = cv::INTER_LINEAR,
                          int borderMode = cv::BORDER_CONSTANT,
                          const cv::Scalar& borderValue = cv::Scalar());

    // 围绕任意旋转中心旋转，可选择自动扩展画布以完整容纳旋转后图像
    static cv::Mat RotateAround(const cv::Mat& src,
                                double angleDeg,
                                cv::Point2f center,
                                double scale = 1.0,
                                bool expandCanvas = false,
                                int interpolation = cv::INTER_LINEAR,
                                int borderMode = cv::BORDER_CONSTANT,
                                const cv::Scalar& borderValue = cv::Scalar());

    // ====== 仿射变换 ======
    // 使用 3 对对应点计算 2x3 仿射矩阵并变换
    static cv::Mat Affine(const cv::Mat& src,
                          const std::vector<cv::Point2f>& srcPts, // 3 点
                          const std::vector<cv::Point2f>& dstPts, // 3 点
                          cv::Size dstSize = cv::Size(),
                          int interpolation = cv::INTER_LINEAR,
                          int borderMode = cv::BORDER_CONSTANT,
                          const cv::Scalar& borderValue = cv::Scalar());

    // 已有 2x3 仿射矩阵的情况
    static cv::Mat AffineWithMatrix(const cv::Mat& src,
                                    const cv::Mat& M2x3,
                                    cv::Size dstSize = cv::Size(),
                                    int interpolation = cv::INTER_LINEAR,
                                    int borderMode = cv::BORDER_CONSTANT,
                                    const cv::Scalar& borderValue = cv::Scalar());

    // ====== 透视变换 ======
    // 使用 4 对对应点计算 3x3 透视矩阵并变换
    static cv::Mat Perspective(const cv::Mat& src,
                               const std::vector<cv::Point2f>& srcPts, // 4 点
                               const std::vector<cv::Point2f>& dstPts, // 4 点
                               cv::Size dstSize,
                               int interpolation = cv::INTER_LINEAR,
                               int borderMode = cv::BORDER_CONSTANT,
                               const cv::Scalar& borderValue = cv::Scalar());

    // 已有 3x3 透视矩阵的情况
    static cv::Mat PerspectiveWithMatrix(const cv::Mat& src,
                                         const cv::Mat& H3x3,
                                         cv::Size dstSize,
                                         int interpolation = cv::INTER_LINEAR,
                                         int borderMode = cv::BORDER_CONSTANT,
                                         const cv::Scalar& borderValue = cv::Scalar());

    // ====== 矩阵辅助生成 ======
    static cv::Matx23f MakeTranslationMatrix(double shiftX, double shiftY);
    static cv::Matx23f MakeRotationMatrix(double angleDeg, cv::Point2f center, double scale = 1.0);
    static cv::Matx33f MakePerspectiveMatrix(const std::vector<cv::Point2f>& srcPts,
                                             const std::vector<cv::Point2f>& dstPts);

private:
    // 计算旋转后完整包围盒（expandCanvas=true 时使用）
    static cv::Size ComputeRotatedBounds(const cv::Mat& src, const cv::Matx23f& M, cv::Matx23f& M_adjusted);
    static bool IsValidImage(const cv::Mat& img);
};

#endif //QTVISIONTEST_GEOMETRICTRANSFORMER_H
